home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / source.exe / POSIX / LD / LD.C next >
C/C++ Source or Header  |  1993-07-09  |  18KB  |  840 lines

  1. /*
  2.       File : ld.c
  3.  
  4.       Author : C S Palkar
  5.  
  6.       Function : Front end for 'ld' to be POSIX complient
  7.  
  8.       Details : The 'ld' command will be invoked it options
  9.                 scaned for validity and an equivalent command
  10.                 constructed for the native link editor, this
  11.                 command is passed to a deamon OR if possible
  12.                 execed.
  13.  
  14.       Date : 23 June 93
  15. */
  16.  
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <fcntl.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #define PNULL(p)          (p*)NULL
  25. #define RNULL             PNULL(rev_cell)
  26. #define NNULL             PNULL(nat_cell)
  27. #define GNULL             PNULL(gnu_cell)
  28. #define SNULL             PNULL(char)
  29.  
  30. #define OPT_TAG           '-'       /* Option tag */
  31. #define EQU               '='       /* EQU */
  32. #define NL                "\n"      /* EOL */
  33. #define OP_CHAR           '/'      /* native opt tag */
  34. #define SP_CHAR           ' '       /* native arg sep */
  35. #define CNULL             '\0'      /* string terminator */
  36.  
  37. #define PT_SEP            "/"      /* Path seperator */
  38.  
  39. #define ST_LIST           "["       /* Trial list start */
  40. #define SP_LIST           "|"       /* Trial list end */
  41. #define ED_LIST           "]"       /* Trial list end */
  42.  
  43. #define LIB_PPATH          "LIB" /* Lib path env var */
  44. #define NO_LINK           "c"       /* Opt for no lnk */
  45.  
  46. #define CWD               "cwd"     /* Delmiter for path list */
  47. #define HOST_CC           "link"   /* Host 'C' complier */
  48. #define TMP_ENV           "TMP"     /* Env var for tmp dir */
  49. #define TMP_DIR           "/tmp"    /* Default tmp dir */
  50. #define option(a)   ((a) == OPT_TAG )
  51.  
  52. #ifdef DEAMON
  53. #define   D_TMP           "tmp.ld"      /* Input of deamon */
  54. #define   D_IN            "devsem.ini"  /* Input of deamon */
  55. #define   D_OUT           "devsem.out"  /* Output of deamon */
  56. #define   D_ERR           "devsem.err"  /* Error of deamon */
  57. #endif
  58.  
  59. typedef enum { FALSE , TRUE } boolean;
  60.  
  61. typedef enum                 /* trail list flag */
  62. {
  63.    NO,                  /* No trail list */
  64.    REV,                 /* Reserved list */
  65.    OPEN,                /* Open     list */
  66.    LIBN,                /* LIBNAME       */
  67.    PPATH                 /* lib path      */
  68. } t_info;
  69.  
  70. typedef struct               /* Trail list name and it native equivalent */
  71. {
  72.    char const *gnu_name;
  73.    char const *nat_name;
  74. } rev_cell , rev_list[];
  75.  
  76. typedef struct nat_dummy
  77. {
  78.    char const *nat_name;           /* Native option name */
  79.    struct nat_dummy *after_ptr;    /* After pos for order */
  80.    rev_cell *tran_list;            /* Ptr to list of reserved opts */
  81. } nat_cell, nat_list[];
  82.  
  83. typedef struct 
  84. {
  85.    char const *opt_name;        /* Option name */
  86.    t_info     trail_info;       /* Trail flag */
  87.    rev_cell   *rev_lst;         /* Ptr to trail info */
  88.    char const *opn_lst;         /* Disc list for Usage */
  89.    nat_cell   *nat_ptr;         /* Ptr to equiv native option */
  90. } gnu_cell, gnu_list[];
  91.  
  92. #if DEAMON
  93. typedef struct
  94. {
  95.    char tmp_file[256];
  96.    char out_file[256];
  97.    FILE *de_in;
  98.    FILE *de_out;
  99.    FILE *de_err;
  100. } dm_struct;
  101. #endif
  102.  
  103. typedef struct dummy
  104. {
  105.    struct dummy *nxt;
  106.    char *token;
  107.         boolean optn;
  108. } cmd_cell, *cmd_ptr;
  109.  
  110. /*
  111.     Tables which will help translation
  112. */
  113. rev_list m_rev_lst =
  114. {
  115.     { SNULL , SNULL }
  116. };
  117.  
  118. nat_list nat_lst =
  119. {
  120.     { "ALIGN"    , NNULL , RNULL },      /* 0 */
  121.     { "BASE"   , NNULL , RNULL },      /* 1 */
  122.     { "DEBUG"    , NNULL , RNULL },      /* 2 */
  123.     { "DEBUGTYPE"   , NNULL , RNULL },      /* 3 */
  124.     { "DLL"   , NNULL , RNULL },      /* 4 */
  125.     { "ENTRY"    , NNULL , RNULL },      /* 5 */
  126.     { "FIXED"   , NNULL , RNULL },      /* 6 */
  127.     { "FORCE"   , NNULL , RNULL },      /* 7 */
  128.     { "GPSIZE"    , NNULL , RNULL },      /* 8 */
  129.     { "HEAP"  , NNULL , RNULL },      /* 9 */
  130.     { "INCLUDE"   , NNULL , RNULL },      /* 10 */
  131.     { "MACHINE"   , NNULL , RNULL },      /* 11 */
  132.     { "MAP"   , NNULL , RNULL },      /* 12 */
  133.     { "OUT" , NNULL , RNULL },      /* 13 */
  134.     { "ROM"  , NNULL , RNULL },      /* 14 */
  135.     { "SECTION"   , NNULL , RNULL },      /* 15 */
  136.     { "STACK"    , NNULL , RNULL },      /* 16 */
  137.     { "SUBSYSTEM"    , NNULL , RNULL },      /* 17 */
  138.     { "VERBOSE"    , NNULL , RNULL },      /* 18 */
  139.     { "VERSION"    , NNULL , RNULL },      /* 19 */
  140.     { SNULL , NNULL , RNULL }
  141. };
  142.  
  143. gnu_list gnu_lst =
  144. {
  145.     { "a"           , NO , RNULL , SNULL ,  nat_lst + 6 },
  146.     { "e"           , OPEN , RNULL , "<entry-point>" ,  nat_lst + 5 },
  147.     { "f"           , OPEN , RNULL , "<pattern>" ,  NNULL },
  148.     { "l"           , LIBN , RNULL , "<lib-name>" ,  nat_lst },
  149.     { "m"           , NO , RNULL , SNULL ,  NNULL },
  150.     { "o"           , OPEN , RNULL , "<file>" ,  nat_lst + 13 },
  151.     { "r"           , NO , RNULL , SNULL ,  NNULL },
  152.     { "s"           , NO , RNULL , SNULL ,  NNULL },
  153.     { "t"           , NO , RNULL , SNULL ,  NNULL },
  154.     { "u"           , OPEN , RNULL , "<symbol>" ,  NNULL },
  155.     { "x"           , NO , RNULL , SNULL ,  NNULL },
  156.     { "z"           , NO , RNULL , SNULL ,  NNULL },
  157.     { "L"           , PPATH , RNULL , "<dir-path>" ,  nat_lst },
  158.     { "M"           , NO , RNULL , SNULL ,  NNULL },
  159.     { "N"           , NO , RNULL , SNULL ,  NNULL },
  160.     { "V"           , NO , RNULL , SNULL ,  NNULL },
  161.     { "VS"          , OPEN , RNULL , "<ver-num>" ,  nat_lst + 19 },
  162.     { SNULL         , NO , RNULL , SNULL , NNULL }
  163. };
  164.  
  165. cmd_cell head_cell , *head_ptr , *end_ptr;
  166. cmd_cell path_cell , *path_ptr , *pend_ptr;
  167. int no_path = 1;
  168.  
  169. char *link_opts[] = /* Default linker options */
  170. {
  171.    "subsystem:posix",
  172.    "entry:__PosixProcessStartup",
  173.    SNULL
  174. };
  175.  
  176. char *def_lib[] = /* Default library */
  177. {
  178.    "libcpsx.lib",
  179.    "psxdll.lib",
  180.    "ntdll.lib",
  181.    "psxrtl.lib",
  182.    SNULL
  183. };
  184.  
  185. /*
  186.        Function : display_rev_lst()
  187.  
  188.        Discription : To display reserved word(s) with option
  189.  
  190.        Called by : usage()
  191. */
  192. void
  193. #ifdef __STDC__
  194. display_rev_lst( rev_list *rev_lst )
  195. #else
  196. display_rev_lst( rev_lst )
  197. rev_cell *rev_lst;
  198. #endif
  199. {
  200.    fputs(ST_LIST,stderr);
  201.  
  202.    while ( rev_lst->gnu_name != ( char const * ) NULL )
  203.    {
  204.       fputs(rev_lst->gnu_name,stderr);
  205.       fputs(SP_LIST,stderr);
  206.       fputs(NL,stderr);
  207.       rev_lst++;
  208.    }
  209. }
  210.  
  211. /*
  212.  
  213.    Function : print_list()
  214.  
  215.    Discription : Initialise linked list
  216.  
  217.    Called by : main()
  218.  
  219. */
  220.  
  221. void
  222. #ifdef __STDC__
  223. print_list( cmd_ptr ptr , FILE * fp )
  224. #else
  225. print_list( ptr , fp )
  226. cmd_ptr ptr;
  227. FILE *fp;
  228. #endif
  229. {
  230.    cmd_ptr tmp;
  231.  
  232.    tmp = ptr;
  233.    
  234.    do
  235.    {
  236.       if ( ptr->optn == TRUE )
  237.          fputc( OP_CHAR , fp );
  238.       fputs(ptr->token,fp);
  239.       fputs( NL , fp );
  240.       ptr = ptr->nxt;
  241.    }
  242.    while ( ptr != tmp );
  243. }
  244.  
  245.  
  246. #ifdef DEAMON
  247. /*
  248.        Function : deamon()
  249.  
  250.        Discription : To identify if deamon() is there and open associated
  251.                      files.
  252.  
  253.        Called by : main()
  254. */
  255. dm_struct
  256. #ifdef __STDC__
  257. *deamon(char const *temp_env,
  258.         char const *temp_path,
  259.         char const *de_in,
  260.         char const *de_out,
  261.         char const *de_err)
  262. #else
  263. *deamon(temp_env, temp_path, de_in, de_out, de_err,de_tmp)
  264. char const *temp_env;
  265. char const *temp_path;
  266. char const *de_in;
  267. char const *de_out;
  268. char const *de_err;
  269. #endif
  270. {
  271.    static dm_struct dm_st;
  272.    char *tmp_dir, t_buff[256];
  273.    struct stat s_buff;
  274.    int fd;
  275.  
  276.    if (( tmp_dir = getenv(temp_env)) == ( char * ) NULL )
  277.       return(( dm_struct * ) NULL );
  278.  
  279.    strcpy( t_buff , tmp_dir );
  280.    strcat( strcat ( t_buff , PT_SEP ) , de_in );
  281.    strcpy( dm_st.out_file , t_buff );
  282.  
  283.    while ( stat(t_buff,&s_buff) == 0 )  /* Wait for DEAMON to get free */
  284.      sleep(2);
  285.  
  286.    strcpy( t_buff , tmp_dir );
  287.    strcat( strcat ( t_buff , PT_SEP ) , de_tmp );
  288.    strcpy( dm_st.tmp_file , t_buff );
  289.  
  290.    if (( fd = creat( t_buff , ( mode_t ) 0777 )) != -1 )
  291.    {
  292.       close(fd);
  293.       if (( dm_st.de_in = fopen( t_buff, "w" )) != ( FILE * ) NULL )
  294.          return( &dm_st );
  295.    }
  296.    return(( dm_struct * ) NULL );
  297.  
  298. #if 0
  299.    if (( dm_st.de_in = fopen( t_buff , "w" )) == ( FILE * ) NULL )
  300.       return(( dm_struct * ) NULL );
  301.  
  302.    strcpy( t_buff , tmp_dir );
  303.    strcat( strcat ( t_buff , PT_SEP ) , de_out );
  304.  
  305.    if (( dm_st.de_out = fopen( t_buff , "r" )) == ( FILE * ) NULL )
  306.       return(( dm_struct * ) NULL );
  307.  
  308.    strcpy( t_buff , tmp_dir );
  309.    strcat( strcat ( t_buff , PT_SEP ) , de_err );
  310.  
  311.    if (( dm_st.de_err = fopen( t_buff , "r" )) == ( FILE * ) NULL )
  312.       return(( dm_struct * ) NULL );
  313.  
  314.    return( &dm_st );
  315. #endif
  316. }
  317.  
  318. /*
  319.        Function : disp_deamon()
  320.  
  321.        Discription : To display messages retunred by deamon
  322.  
  323.        Called by : main()
  324. */
  325. int
  326. #ifdef __STDC__
  327. disp_deamon(FILE *fderr)
  328. #else
  329. disp_deamon(fderr)
  330. FILE *fderr;
  331. #endif
  332. {
  333.    return 0;
  334. }
  335.  
  336. /*
  337.        Function : wait_deamon()
  338.  
  339.        Discription : To wait for deamon to finish job
  340.  
  341.        Called by : main()
  342. */
  343. int
  344. #ifdef __STDC__
  345. wait_deamon(char *fdin)
  346. #else
  347. wait_deamon(fdin)
  348. char *fdin;
  349. #endif
  350. {
  351.    FILE *fd;
  352.  
  353.    while ((fd=fopen(fdin,"r")) != ( FILE *) NULL )
  354.    {
  355.       fclose(fd);
  356.       sleep(1);
  357.    }
  358.    return 0;
  359. }
  360.  
  361. /*
  362.        Function : writ_deamon()
  363.  
  364.        Discription : To write to deamon I/P file the new command
  365.  
  366.        Called by : main()
  367. */
  368. int
  369. #ifdef __STDC__
  370. writ_deamon(cmd_cell *head_ptr, FILE *fdout)
  371. #else
  372. writ_deamon(head_ptr, fdout)
  373. cmd_cell *head_ptr;
  374. FILE *fdout;
  375. #endif
  376. {
  377.    char buff[64];
  378.    int i;
  379.  
  380.    if ( !no_path )
  381.    {
  382.      fputs(LIB_PPATH,fdout);
  383.      fputs( NL , fdout );
  384.      print_list( path_ptr , fdout );
  385.    }
  386.  
  387.    fprintf(fdout,"%s\n",CWD);
  388.  
  389.    i =  sizeof( buff );
  390.    if ( getcwd( buff , ( size_t )i ) == CNULL )
  391.       return 0;
  392.    fprintf(fdout,"%s\n",buff);
  393.    print_list( head_ptr , fdout );
  394.  
  395.    for ( i = 0 ; link_opts[i] != SNULL ; i++ )
  396.    {
  397.       fputc( OP_CHAR , fdout );
  398.       fputs(link_opts[i],fdout);
  399.       fputs( NL , fdout );
  400.    }
  401.  
  402.    for ( i = 0 ; def_lib[i] != SNULL ; i++ )
  403.    {
  404.       fputs(def_lib[i],fdout);
  405.       fputs( NL , fdout );
  406.    }
  407.    fclose( fdout );
  408.    return 1;
  409. }
  410. #else
  411. /*
  412.        Function : exec_cmd()
  413.  
  414.        Discription : To exec the new command
  415.  
  416.        Called by : main()
  417. */
  418. int
  419. #ifdef __STDC__
  420. exec_cmd(cmd_cell *head_ptr)
  421. #else
  422. exec_cmd(head_ptr)
  423. cmd_cell *head_ptr;
  424. #endif
  425. {
  426.    return 0;
  427. }
  428. #endif
  429.  
  430. /*
  431.        Function : usage()
  432.  
  433.        Discription : To identify if if USAGE of command is correct
  434.  
  435.        Called by : main()
  436. */
  437. int
  438. #ifdef __STDC__
  439. usage(int argc, char *argv)
  440. #else
  441. usage(argc,argv)
  442.    int argc;
  443.    char *argv;
  444. #endif
  445. {
  446.    gnu_cell *gnu_ptr;
  447.    int new_opt;
  448.  
  449.    new_opt = TRUE;
  450.    gnu_ptr = gnu_lst;
  451.  
  452.    if ( argc > 1 )
  453.       return 0;
  454.  
  455.    fprintf(stderr,"\nUseage : %s ",argv);
  456.  
  457.    while ( gnu_ptr->opt_name != ( char const * ) NULL )
  458.    {
  459.       if ( new_opt == TRUE )
  460.       {
  461.          fputc(OPT_TAG,stderr);
  462.          new_opt = FALSE;
  463.       }
  464.       fputs(gnu_ptr->opt_name,stderr);
  465.       switch ( gnu_ptr->trail_info )
  466.       {
  467.          case NO   : new_opt = TRUE;
  468.                 break;
  469.          case REV  : display_rev_lst( gnu_ptr->rev_lst );
  470.                 new_opt = TRUE;
  471.                 break;
  472.          case LIBN :
  473.          case PPATH :
  474.          case OPEN : fputs(gnu_ptr->opn_lst,stderr);
  475.                 new_opt = TRUE;
  476.                 break;
  477.          default   : fprintf(stderr,"ERROR : Internal error \n");
  478.                 break;
  479.       }
  480.       fputc(SP_CHAR,stderr);
  481.       gnu_ptr++;
  482.    }
  483.    fputs(NL,stderr);
  484.    return 1;
  485. }
  486.  
  487. /*
  488.  
  489.    Function : init_list()
  490.  
  491.    Discription : Initialise linked list
  492.  
  493.    Called by : main()
  494.  
  495. */
  496.  
  497. cmd_ptr
  498. #ifdef __STDC__
  499. init_list( cmd_ptr cell , char * str )
  500. #else
  501. init_list( cell , str , end_ptr )
  502. cmd_ptr cell;
  503. char *str; 
  504. #endif
  505. {
  506.    cell->token = str;
  507.    cell->optn = FALSE;
  508.    cell->nxt = cell;
  509.    return( cell );
  510. }
  511.  
  512. /*
  513.  
  514.    Function : del_list()
  515.  
  516.    Discription : Delete list
  517.  
  518.    Called by : main()
  519.  
  520. */
  521.  
  522. void
  523. #ifdef __STDC__
  524. del_list( cmd_ptr ptr )
  525. #else
  526. del_list( ptr )
  527. cmd_ptr ptr;
  528. #endif
  529. {
  530.    cmd_ptr tmp, tmp2;
  531.  
  532.    if ( ptr == ptr->nxt )
  533.       return;
  534.  
  535.    tmp = ptr;
  536.    ptr = ptr->nxt;
  537.    
  538.    do
  539.    {
  540.       tmp2 = ptr->nxt;
  541.       free( ptr );
  542.       ptr = tmp2;
  543.    }
  544.    while ( ptr != tmp );
  545. }
  546.  
  547.  
  548. /*
  549.  
  550.    Function : new_cell()
  551.  
  552.    Discription : Create new node
  553.  
  554.    Called by : main()
  555.  
  556. */
  557.  
  558. cmd_ptr
  559. #ifdef __STDC__
  560. new_cell( char *str, boolean optn )
  561. #else
  562. new_cell( str , optn )
  563. char *str;
  564. boolean optn;
  565. #endif
  566. {
  567.    cmd_ptr ptr;
  568.  
  569.    if (( ptr = (cmd_ptr)malloc(sizeof(cmd_cell))) == (cmd_ptr) NULL )
  570.       return (( cmd_ptr ) NULL );
  571.    ptr->token = str;
  572.    ptr->optn  = optn;
  573.    return ptr;
  574. }
  575.  
  576. /*
  577.  
  578.    Function : add_list()
  579.  
  580.    Discription : Add at current pos
  581.  
  582.    Called by : main()
  583.  
  584. */
  585.  
  586. cmd_ptr
  587. #ifdef __STDC__
  588. add_list( cmd_ptr ptr , cmd_ptr node )
  589. #else
  590. add_list( ptr , node )
  591. cmd_ptr ptr, node;
  592. #endif
  593. {
  594.    node->nxt = ptr->nxt;
  595.    ptr->nxt = node;
  596.    return node;
  597. }
  598.  
  599. /*
  600.  
  601.    Function : equiv_name()
  602.  
  603.    Discription : Searchs for equivalent name for native
  604.             and returns pointer to base.
  605.  
  606.    Called by : process_opt()
  607.  
  608. */
  609.  
  610. char
  611. #ifdef __STDC__
  612. *equiv_name( rev_cell *ptr , char *str )
  613. #else
  614. *equiv_name( ptr , str )
  615. rev_cell *ptr; 
  616. char *str;
  617. #endif
  618. {
  619.    while ( ptr->gnu_name != ( char const * ) NULL )
  620.       if ( strcmp(ptr->gnu_name,str) == 0 )
  621.          return ( char * ) ptr->nat_name;
  622.       else
  623.          ptr++;
  624.  
  625.    return ( char * ) NULL;
  626. }
  627.  
  628. /*
  629.  
  630.    Function : process_opt()
  631.  
  632.    Discription : Check if equivalent option exists
  633.  
  634.    Called by : main()
  635.  
  636. */
  637.  
  638. int
  639. #ifdef __STDC__
  640. process_opt( char *ch_ptr , gnu_cell *gnu_ptr , int *arg_cnt , char **argv )
  641. #else
  642. process_opt( ch_ptr , gnu_ptr , arg_cnt , argv )
  643. char *ch_ptr;
  644. gnu_cell *gnu_ptr;
  645. int *arg_cnt;
  646. char **argv;
  647. #endif
  648. {
  649.    cmd_ptr cell_ptr;
  650.    char    *tmp_ptr;
  651.    int      len;
  652.  
  653.    len = strlen(gnu_ptr->opt_name);
  654.  
  655.    if ( gnu_ptr->trail_info == PPATH || gnu_ptr->trail_info == LIBN )
  656.    {
  657.       if ( *( ch_ptr + len ) != CNULL )
  658.          ch_ptr += len;
  659.       else
  660.          ch_ptr = argv[++*arg_cnt];
  661.  
  662.      if ( gnu_ptr->trail_info ==  PPATH )
  663.      {
  664.         if ( no_path )
  665.         {
  666.            no_path = 0;
  667.            pend_ptr = path_ptr = init_list( &path_cell , ch_ptr );
  668.         }
  669.         else
  670.         {
  671.             if (( cell_ptr = new_cell(ch_ptr, FALSE )) == ( cmd_ptr ) NULL )
  672.             {
  673.                fprintf(stderr,"ERROR : No mem!\n");
  674.                return 0;
  675.             }
  676.             pend_ptr = add_list( pend_ptr , cell_ptr );
  677.         }
  678.     }
  679.     else
  680.     {
  681.        if (( tmp_ptr = (char *)malloc( strlen(ch_ptr) + 6 )) == SNULL )
  682.        {
  683.           fprintf(stderr,"ERROR : No mem!\n");
  684.           return 0;
  685.        }
  686.  
  687.        strcat(strcat(strcpy(tmp_ptr,"lib"),ch_ptr),".a");
  688.  
  689.        if (( cell_ptr = new_cell(tmp_ptr, FALSE )) == ( cmd_ptr ) NULL )
  690.        {
  691.           fprintf(stderr,"ERROR : No mem!\n");
  692.           return 0;
  693.        }
  694.        end_ptr = add_list( end_ptr , cell_ptr );
  695.     }
  696.     return 1;
  697.   }
  698.    if (( cell_ptr = new_cell(gnu_ptr->nat_ptr->nat_name , TRUE )) == ( cmd_ptr ) NULL )
  699.    {
  700.       fprintf(stderr,"ERROR : No mem!\n");
  701.       return 0;
  702.    }
  703.  
  704.    end_ptr = add_list( end_ptr , cell_ptr );
  705.  
  706.    if ( gnu_ptr->trail_info == NO )
  707.       return strlen(ch_ptr) == strlen(gnu_ptr->opt_name);
  708.  
  709.    if ( *( ch_ptr + len ) != CNULL )
  710.       ch_ptr += len;
  711.    else
  712.       ch_ptr = argv[++*arg_cnt];
  713.  
  714.    if ( gnu_ptr->trail_info != OPEN )
  715.       if (( ch_ptr = equiv_name(gnu_ptr->rev_lst,ch_ptr)) != ( char * ) NULL )
  716.          return 0;
  717.  
  718.     tmp_ptr = ( char * )gnu_ptr->nat_ptr->nat_name;
  719.  
  720.     if ((tmp_ptr=(char*)malloc(strlen(ch_ptr)+strlen(tmp_ptr)+2)) == SNULL )
  721.     {
  722.        fprintf(stderr,"ERROR : No mem!\n");
  723.        return 0;
  724.     }
  725.     
  726.     strcat(strcat(strcpy(tmp_ptr,gnu_ptr->nat_ptr->nat_name ),":"),ch_ptr);
  727.  
  728.      cell_ptr->token = tmp_ptr;
  729.      return 1;
  730. }
  731.  
  732. /*
  733.  
  734.    Function : in_opt_list()
  735.  
  736.    Discription : Identify option and return ptr to table entry
  737.  
  738.    Called by : main()
  739.  
  740. */
  741.  
  742. gnu_cell 
  743. #ifdef __STDC__
  744. *in_opt_list( char *ch_ptr )
  745. #else
  746. *in_opt_list( ch_ptr )
  747. char *ch_ptr;
  748. #endif
  749. {
  750.    gnu_cell *gnu_ptr;
  751.    char *tmp_ptr;
  752.  
  753.    gnu_ptr = gnu_lst;
  754.  
  755.    while (( tmp_ptr = ( char * )gnu_ptr->opt_name ) != SNULL )
  756.    {
  757.       if (strncmp(ch_ptr,tmp_ptr,strlen(tmp_ptr))==0 )
  758.          if ( gnu_ptr->nat_ptr != NNULL )
  759.            return gnu_ptr ;
  760.       gnu_ptr++;
  761.    }
  762.    return GNULL;
  763. }
  764.  
  765. int
  766. #ifdef __STDC__
  767. main(int argc, char **argv)
  768. #else
  769. main(argc,argv)
  770.    int argc;
  771.    char ** argv;
  772. #endif
  773. {
  774. #ifdef DEAMON
  775.    dm_struct *dm_ptr;
  776. #endif
  777.    char *arg_ptr, *ch_ptr;
  778.    cmd_ptr tmp_ptr;
  779.    gnu_cell *gnu_ptr;
  780.    int i;
  781.  
  782.    if ( usage(argc,argv[0]))
  783.       return 0;
  784.  
  785. #if DEAMON
  786.    if((dm_ptr=deamon(TMP_ENV,TMP_DIR,D_IN,D_OUT,D_ERR,D_TMP))==(dm_struct*)NULL)
  787.    {
  788.       fprintf(stderr,"Cannot execute %s deamon missing\n",*argv[0]);
  789.       return 0;
  790.    }
  791. #endif
  792.  
  793.    end_ptr = head_ptr = init_list( &head_cell , HOST_CC );
  794.  
  795.    i = 0;
  796.  
  797.    while ( ++i < argc )
  798.    {
  799.       arg_ptr = *( argv + i );
  800.  
  801.       if ( !option(*arg_ptr))
  802.       {
  803.          if (( tmp_ptr = new_cell(arg_ptr,FALSE)) == ( cmd_ptr ) NULL )
  804.          {
  805.             fprintf(stderr,"Insufficient memory EXITING!\n");
  806.             return 0;
  807.          }
  808.          end_ptr = add_list( end_ptr , tmp_ptr );
  809.       }   
  810.       else
  811.       {
  812.          ch_ptr = arg_ptr;
  813.          ch_ptr++;
  814.  
  815.          while ( *ch_ptr != ( char )NULL )
  816.          {
  817.             if (( gnu_ptr = in_opt_list(ch_ptr)) != ( gnu_cell * ) NULL )
  818.                if ( process_opt(ch_ptr,gnu_ptr,&i,argv))
  819.                   break;
  820.             ch_ptr++;
  821.          }
  822.       }
  823.    }
  824.  
  825. #if DEAMON
  826.    if ( !writ_deamon( head_ptr , dm_ptr->de_in ))
  827.    {
  828.       fprintf(stderr,"Unable to communicate with DEAMON. EXITING!\n");
  829.       return 0;
  830.    }
  831.    rename( dm_ptr->tmp_file, dm_ptr->out_file );
  832.    wait_deamon( dm_ptr->out_file );
  833.    disp_deamon( dm_ptr->de_err );
  834. #else
  835.    exec_cmd( head_ptr );
  836. #endif
  837.    del_list( head_ptr );
  838.    return 0;
  839. }
  840.